﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace MvdDonk.Bomberman.Entities
{
    class Player : Entity
    {
        public PlayerState MovementState { get; set; }

        private double IdleTimer = 0;
        public long NetworkId { get; set; }
        public string ClientName { get; set; }
        protected Dictionary<PlayerState, List<Rectangle>> spriteMovementRectangles;

        public bool IsLocalPlayer
        {
            get
            {
                return Bomberman.Instance.NetworkManager.Client.NetworkId == NetworkId || NetworkId == -1;
            }
        }

        public Player(Texture2D sprite, Vector2 position, long networkId, string clientName)
            : base(sprite, position)
        {
            NetworkId = networkId;
            ClientName = clientName;
            spriteMovementRectangles = new Dictionary<PlayerState, List<Rectangle>>()
            {
                { 
                    PlayerState.Idle,
                    new List<Rectangle>()
                    {
                        new Rectangle(0, 0, spriteWidth, spriteHeight),
                        new Rectangle(spriteWidth, 0, spriteWidth, spriteHeight)
                    }
                },
                { 
                    PlayerState.WalkingDown, 
                    new List<Rectangle>()
                    {
                        new Rectangle(2 * spriteWidth, 0, spriteWidth, spriteHeight),
                        new Rectangle(3 * spriteWidth, 0, spriteWidth, spriteHeight)
                    }
                },
                { 
                    PlayerState.WalkingUp, 
                    new List<Rectangle>()
                    {
                        new Rectangle(spriteWidth, spriteHeight, spriteWidth, spriteHeight),
                        new Rectangle(2 * spriteWidth, spriteHeight, spriteWidth, spriteHeight)
                    }
                },
                { 
                    PlayerState.WalkingLeft, 
                    new List<Rectangle>()
                    {
                        new Rectangle(3 * spriteWidth, 2 * spriteHeight, spriteWidth, spriteHeight),
                        new Rectangle(0, 3 * spriteHeight, spriteWidth, spriteHeight)
                    }
                },
                { 
                    PlayerState.WalkingRight,
                    new List<Rectangle>()
                    {
                        new Rectangle(0, 2 * spriteHeight, spriteWidth, spriteHeight),
                        new Rectangle(spriteWidth, 2 * spriteHeight, spriteWidth, spriteHeight)
                    }
                }
            };
        }

        private void DoMovement(GameTime gameTime, TiledLib.Map map)
        {
            //Place bomb?
            if (Bomberman.Instance.InputManager.GetPressedKeys().Contains(Keys.Space))
            {
                Bomberman.Instance.EntityManager.AddEntity(new Bomb(Bomberman.Instance.TestBombTexture, Position));
            }

            var collisionLayer = (TiledLib.TileLayer)map.GetLayer("Meta");
            MovementVector = new Vector2();
            //var currentSpeed = Speed * gameTime.ElapsedGameTime.TotalMilliseconds;
            if (Bomberman.Instance.InputManager.KeyDown(Keys.Left))
            {
                var velocity = new Vector2(Speed, 0);
                Vector2 corner1 = Position + new Vector2(0, TileMargin) + velocity;
                Vector2 corner2 = Position + new Vector2(0, spriteHeight - TileMargin) + velocity;

                // check one corner to make sure it's still on the map
                if (corner1.X > 0)
                {
                    // check for a collision
                    Point point1 = map.WorldPointToTileIndex(corner1);
                    Point point2 = map.WorldPointToTileIndex(corner2);

                    if (collisionLayer == null ||
                        (collisionLayer.Tiles[point1.X, point1.Y] == null
                        && collisionLayer.Tiles[point2.X, point2.Y] == null))
                    {
                        MovementVector.X -= Speed;
                    }
                }
            }
            if (Bomberman.Instance.InputManager.KeyDown(Keys.Right))
            {
                var velocity = new Vector2(-Speed, 0);
                Vector2 corner1 = Position + new Vector2(spriteWidth, 0) + new Vector2(0, TileMargin) + velocity;
                Vector2 corner2 = Position + new Vector2(spriteWidth, 0) + new Vector2(0, spriteHeight - TileMargin) + velocity;

                // check one corner to make sure it's still on the map
                if (corner1.X < 800)
                {
                    // check for a collision
                    Point point1 = map.WorldPointToTileIndex(corner1);
                    Point point2 = map.WorldPointToTileIndex(corner2);

                    if (collisionLayer == null ||
                        (collisionLayer.Tiles[point1.X, point1.Y] == null
                        && collisionLayer.Tiles[point2.X, point2.Y] == null))
                    {
                        MovementVector.X += Speed;
                    }
                }
            }

            if (Bomberman.Instance.InputManager.KeyDown(Keys.Up))
            {
                var velocity = new Vector2(0, Speed);
                Vector2 corner1 = Position + new Vector2(TileMargin, 0) + velocity;
                Vector2 corner2 = Position + new Vector2(spriteWidth - TileMargin, 0) + velocity;

                // check one corner to make sure it's still on the map
                if (corner1.Y > 0)
                {
                    // check for a collision
                    Point point1 = map.WorldPointToTileIndex(corner1);
                    Point point2 = map.WorldPointToTileIndex(corner2);

                    if (collisionLayer == null ||
                        (collisionLayer.Tiles[point1.X, point1.Y] == null
                        && collisionLayer.Tiles[point2.X, point2.Y] == null))
                    {
                        MovementVector.Y -= Speed;
                    }
                }
            }
            if (Bomberman.Instance.InputManager.KeyDown(Keys.Down))
            {
                var velocity = new Vector2(0, -Speed);
                Vector2 corner1 = Position + new Vector2(0, spriteHeight) + new Vector2(TileMargin, 0) + velocity;
                Vector2 corner2 = Position + new Vector2(0, spriteHeight) + new Vector2(spriteWidth - TileMargin, 0) + velocity;

                // check one corner to make sure it's still on the map
                if (corner1.Y < 600)
                {
                    // check for a collision
                    Point point1 = map.WorldPointToTileIndex(corner1);
                    Point point2 = map.WorldPointToTileIndex(corner2);

                    if (collisionLayer == null ||
                        (collisionLayer.Tiles[point1.X, point1.Y] == null
                        && collisionLayer.Tiles[point2.X, point2.Y] == null))
                    {
                        MovementVector.Y += Speed;
                    }
                }
            }

            if (MovementVector.X == 0 && MovementVector.Y == 0)
                MovementState = PlayerState.Idle;
            else
            {
                if (MovementVector.Y > 0)
                    MovementState = PlayerState.WalkingDown;
                else if (MovementVector.Y < 0)
                    MovementState = PlayerState.WalkingUp;

                if (MovementVector.X < 0)
                    MovementState = PlayerState.WalkingLeft;
                else if (MovementVector.X > 0)
                    MovementState = PlayerState.WalkingRight;
            }

            Position += MovementVector;
        }

        public override void Update(GameTime gameTime, TiledLib.Map map)
        {
            base.Update(gameTime, map);
            IdleTimer += gameTime.ElapsedGameTime.TotalMilliseconds;

            if (IdleTimer > (MovementState == PlayerState.Idle ? 500 : 100))
            {
                IdleTimer = 0;
                currentFrame++;
                if (currentFrame > 1)
                    currentFrame = 0;
            }

            if (IsLocalPlayer)
            {
                DoMovement(gameTime, map);
            }
            else
            {
                Position += MovementVector;
            }

            
        }

        public override void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(Sprite, Position, spriteMovementRectangles[MovementState][currentFrame], Color.White);
        }
    }
}
